package com.qianli.cashmama.product.server.controller.pay2;

import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Author shm
 * Desc
 * Date 2022/4/6 21:48
 */
public final class MD5SignUtil {

    private static final char[] MD5_TO_STRING_CHARS = new char[]{'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};


    public static <T> String digestResData(T obj, String signKey){
        String dataKey = preHandleObject(obj);
        dataKey = dataKey + "&signKey=" +signKey;
        return doDigest(dataKey);
    }

    private static <T> String preHandleObject(final T obj){
        Field[] fields = obj.getClass().getDeclaredFields();
        if(!ObjectUtils.isEmpty(fields)){
           List<String> keyValues =  Arrays.stream(fields)
                   .sorted(Comparator.comparing(Field::getName))
                   .map(field -> {
                       try {
                           boolean acc = field.isAccessible();
                           field.setAccessible(true);
                           Object value = field.get(obj);
                           field.setAccessible(acc);
                           if(value != null)
                               return field.getName() + "=" + value;
                       } catch (IllegalAccessException e) {
                       }
                       return null;
                   }).filter(Objects::nonNull)
                   .collect(Collectors.toList());
          return String.join("&", keyValues);
        }
        return "";
    }

    private static String doDigest(String str){
        StringBuilder stringBuffer = new StringBuilder();
        try {
            MessageDigest md5 = MessageDigest.getInstance("md5");
            byte[] digest = md5.digest(str.getBytes(StandardCharsets.UTF_8));

            // 处理成十六进制的字符串(通常)
            for (byte bb : digest) {
                stringBuffer.append(MD5_TO_STRING_CHARS[(bb >> 4) & 15]);
                stringBuffer.append(MD5_TO_STRING_CHARS[bb & 15]);
            }
        } catch (NoSuchAlgorithmException e) {
        }
        return stringBuffer.toString();
    }

}
